package com.example.shardingjdbctest.config;

import com.alibaba.druid.mock.MockConnection;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledPreparedStatement;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.util.jdbc.ConnectionBase;
import org.springframework.cglib.proxy.Enhancer;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.*;

/**
 * @author：kangxuan
 * @date：2024/10/17 4:42 PM
 * @desc:
 */
public class MyConnection extends MockConnection {

    private Connection connection;
    private DruidDataSource dataSource;

    public Connection getConnection() {
        if (connection == null){
            try {
                this.connection = dataSource.getConnection();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        return connection;
    }

    public DruidDataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DruidDataSource dataSource) {
        this.dataSource = dataSource;
    }

    public void setConnection(Connection connection) {
        this.connection = connection;
    }

    @Override
    public PreparedStatement prepareStatement(String sql) throws SQLException {
        return getConnection().prepareStatement(sql);
    }

    @Override
    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
        System.out.println("2：prepareStatement");
        PreparedStatement preparedStatement = getConnection().prepareStatement(sql, resultSetType, resultSetConcurrency);
        // 创建代理的PreparedStatement对象
        Object proxy =  Proxy.newProxyInstance(PreparedStatement.class.getClassLoader()
                , new Class[]{PreparedStatement.class},
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        if (method.getName().equals("execute")){
                            DruidPooledPreparedStatement preparedStatement1 = (DruidPooledPreparedStatement) preparedStatement;
                            String sql1 = preparedStatement1.getSql();
                            ParameterMetaData parameterMetaData = preparedStatement1.getParameterMetaData();
                            System.out.println("sql: " + sql1);

                        }
                        Object invoke = method.invoke(preparedStatement, args);
                        return invoke;
                    }
                });

        return (PreparedStatement) proxy;
    }

    @Override
    public Statement createStatement() throws SQLException {
        return getConnection().createStatement();
    }

    @Override
    public DatabaseMetaData getMetaData() throws SQLException {
        return getConnection().getMetaData();
    }
}
